#pragma once
#include "Open_Hash.h"

template<class K,class HF = Open_Hash::HashFunction<K>>
class unordered_set
{
	struct SetKeyofT
	{
		const K& operator()(const K& key)
		{
			return key;
		}
	};

	typedef Open_Hash::HashBucket<K, K, SetKeyofT, HF> Hash;

public:
	typedef typename Open_Hash::HashBucket<K, K, SetKeyofT, HF>::Iterator iterator;
	typedef typename Open_Hash::HashBucket<K, K, SetKeyofT, HF>::ConstIterator const_iterator;
	iterator begin()
	{
		return _ht.Begin();
	}

	iterator end()
	{
		return _ht.End();
	}
	const_iterator begin() const
	{
		return _ht.Begin();
	}

	const_iterator end() const
	{
		return _ht.End();
	}


	pair<iterator, bool> insert(const K& key)
	{
		return _ht.Insert(key);
	}

	size_t size() const 
	{
		return _ht.Size();
	}

	iterator find(const K& key)
	{
		return _ht.Find(key);
	}

	bool erase(const K& key)
	{
		return _ht.Erase(key);
	}
	bool empty() const 
	{
		return _ht.Empty();
	}
	size_t buckcount()const
	{
		return _ht.BucketCount();
	}
private:
	Hash _ht;
};

void Print(const unordered_set<int>& st)
{
	unordered_set<int>::const_iterator it = st.begin();
	while (it != st.end())
	{
		cout << *it << endl;;
		++it;
	}
}

void test_set()
{
	unordered_set<int> st;
	int a[] = { 1,11,21,3,13,23,4,14,15,16 };
	for (const auto& e : a)
	{
		st.insert(e);
	}
	st.insert(20);
	st.insert(20);
	st.insert(24);

	unordered_set<int>::iterator it = st.begin();
	while (it != st.end())
	{
		cout << *it << endl;;
		++it;
	}

}